package cn.lg.soar.general.service.impl;

import cn.lg.soar.common.util.AssertUtil;
import cn.lg.soar.common.util.data.DataUtil;
import cn.lg.soar.general.api.model.BizFileDTO;
import cn.lg.soar.general.api.model.FileVO;
import cn.lg.soar.general.entity.BizFile;
import cn.lg.soar.general.mapper.BizFileMapper;
import cn.lg.soar.general.service.IBizFileService;
import cn.lg.soar.general.service.IBizFileTypeService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 文件业务关系表
 * @author 41225
 * @since 2024-06-02
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
@Service
public class BizFileServiceImpl extends ServiceImpl<BizFileMapper, BizFile> implements IBizFileService {

    @Autowired
    private IBizFileTypeService bizFileTypeService;

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public boolean saveBizFile(Long bizId, Collection<BizFileDTO> bizFiles) {
        List<BizFile> relations = new ArrayList<>(bizFiles.size() << 3);
        List<Integer> bizTypeIds = new ArrayList<>();
        for (BizFileDTO bizFile : bizFiles) {
            int bizTypeId = bizFileTypeService.typeToId(bizFile.getBizType());
            bizTypeIds.add(bizTypeId);
            List<FileVO> fileVos = bizFile.getFileVos();
            if (DataUtil.isEmpty(fileVos)) {
                continue;
            }
            for (FileVO fileVo : fileVos) {
                BizFile relation = new BizFile();
                relation.setBizTypeId(bizTypeId);
                relation.setBizId(bizId);
                relation.setFileId(fileVo.getId());
                relation.setOriginalName(fileVo.getName());
                relation.setFileSize(fileVo.getSize());
                relation.setFileUrl(fileVo.getUrl());
                relations.add(relation);
            }
        }
        doRemove(bizId, bizTypeIds);
        if (relations.isEmpty()) {
            return true;
        }
        return saveBatch(relations);
    }

    @Override
    public Map<String, List<FileVO>> getBizFile(Long bizId, Collection<String> bizTypes) {
        AssertUtil.notEmpty(bizTypes, "缺少业务类型");
        List<Integer> bizTypeIds = bizTypes.stream().map(bizFileTypeService::typeToId).collect(Collectors.toList());
        List<BizFile> list = list(
                Wrappers.<BizFile>lambdaQuery()
                        .eq(BizFile::getBizId, bizId)
                        .in(BizFile::getBizTypeId, bizTypeIds)
        );
        Map<String, List<FileVO>> res = new HashMap<>(16);
        list.stream()
                .collect(Collectors.groupingBy(BizFile::getBizTypeId))
                .forEach((k, v) -> {
                    List<FileVO> vos = v.stream().map(x -> {
                        FileVO vo = new FileVO();
                        vo.setId(x.getFileId());
                        vo.setName(x.getOriginalName());
                        vo.setSize(x.getFileSize());
                        vo.setUrl(x.getFileUrl());
                        return vo;
                    }).collect(Collectors.toList());
                    res.put(bizFileTypeService.idToType(k), vos);
                });
        return res;
    }

    @Override
    public boolean removeBizFile(Long bizId, Collection<String> bizTypes) {
        AssertUtil.notEmpty(bizTypes, "缺少业务类型");
        List<Integer> bizTypeIds = bizTypes.stream().map(bizFileTypeService::typeToId).collect(Collectors.toList());
        return remove(
                Wrappers.<BizFile>lambdaQuery()
                        .eq(BizFile::getBizId, bizId)
                        .in(BizFile::getBizTypeId, bizTypeIds)
        );
    }

    boolean doRemove(Long bizId, Collection<Integer> bizTypeIds) {
        return remove(
                Wrappers.<BizFile>lambdaQuery()
                        .eq(BizFile::getBizId, bizId)
                        .in(BizFile::getBizTypeId, bizTypeIds)
        );
    }
}
